import com.alibaba.druid.pool.DruidDataSource;
import com.taylor.spring5.aop.ConfigAop;
import com.taylor.spring5.config.Springconfig;
import com.taylor.spring5.config.TxConfig;
import com.taylor.spring5.entity.Emp;
import com.taylor.spring5.entity.Order;
import com.taylor.spring5.entity.Student;
import com.taylor.spring5.entity.User;
import com.taylor.spring5.factoryBean.MyFactoryBean;
import com.taylor.spring5.service.BookService;
import com.taylor.spring5.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.sql.SQLException;

/**
 * @description: 主测试类
 *
 *   加载spring配置文件
 *     Spring 提供 IOC 容器实现两种方式：（两个接口）
 *   （1）BeanFactory：IOC 容器基本实现，是 Spring 内部的使用接口，不提供开发人员进行使用
 *      加载配置文件时候不会创建对象，在获取对象（使用）才去创建对象
 *   （2）ApplicationContext：BeanFactory 接口的子接口，提供更多更强大的功能，一般由开发人
 *   员进行使用
 *   加载配置文件时候就会把在配置文件对象进行创建
 *
 * @author: Taylor
 * @date :  2021-04-01 10:30
 **/
public class Spring5Main {

    @Test
    public void testColleactionBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("collectionBean.xml");
        Student student = applicationContext.getBean("student", Student.class);
        System.out.println(student);
    }
    @Test
    public void testInnerBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("innerbean.xml");
        Emp emp = applicationContext.getBean("emp", Emp.class);
        System.out.println(emp);

    }
    @Test
    public void testOutBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("outbean.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.add();
    }
    @Test
    public void testAdd(){
//        BeanFactory beanFactory = new ClassPathXmlApplicationContext("bean.xml");
        ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("bean.xml");
        //spring方式创建对象
        User user1 = applicationContext.getBean("user", User.class);
        User user2 = applicationContext.getBean("user", User.class);
        /**
         * 测试bean的作用域
         * bean.xml中设置singleton 默认
         * com.taylor.spring5.entity.User@87f383f
         * com.taylor.spring5.entity.User@87f383f
         * bean.xml中设置 prototype
         * com.taylor.spring5.entity.User@1a3869f4
         * com.taylor.spring5.entity.User@a38d7a3
         */
        System.out.println(user1);
        System.out.println(user2);

    }

    /**
     * 测试工厂bean
     */
    @Test
    public void testFactoryBean(){
        ClassPathXmlApplicationContext myfactorybean = new ClassPathXmlApplicationContext("myfactorybean.xml");
        User user = myfactorybean.getBean("myFactoryBean", User.class);
        System.out.println(user);
    }

    /**
     * 测试bean的生命周期
     */
    @Test
    public void testLifeCycle(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("lifecycle.xml");
        Order order = applicationContext.getBean("order", Order.class);
        System.out.println("第四步：获取到bean "+ order);
        //手动销毁
        applicationContext.close();
    }

    /**
     * 测试bean的生命周期
     */
    @Test
    public void testDB() throws SQLException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("dbbean.xml");
        DruidDataSource datasource = (DruidDataSource) applicationContext.getBean("datasource");
        System.out.println("获取数据库连接池： "+ datasource);

    }

    @Test
    public void testConfig(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Springconfig.class);
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.add();
    }

    @Test
    public void testJdbc() throws SQLException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("dbbean.xml");
        BookService bookService = applicationContext.getBean("bookService", BookService.class);
        System.out.println(bookService.add());

    }

    /**
     * 测试事务xml方式
     * @throws SQLException
     */
    @Test
    public void testXMLTx() throws SQLException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("dbbean.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.chgAccount();

    }
    /**
     * 测试事务完全注解方式
     * @throws SQLException
     */
    @Test
    public void testAnnoTx() throws SQLException {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TxConfig.class);
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.chgAccount();

    }
}
